Imports System.ComponentModel
Imports System.Drawing.Drawing2D

Imports Phoenix.Forms.View

Namespace Forms.Login

    Public Class XPLoginScreen
        Inherits ViewBase

#Region " UserListPanel class "
        Public Class UserListPanel : Inherits Panel
            Public Sub New()
                SetStyle(ControlStyles.ResizeRedraw, True)
                SetStyle(ControlStyles.AllPaintingInWmPaint, True)
                SetStyle(ControlStyles.UserPaint, True)
                SetStyle(ControlStyles.DoubleBuffer, True)
                SetStyle(ControlStyles.SupportsTransparentBackColor, True)
                SetStyle(ControlStyles.ContainerControl, True)
                MyBase.BackColor = Color.Transparent
            End Sub
        End Class
#End Region



#Region " Private Fields "
        Private mHeaderHeight As Integer = 48
        Private mFooterHeight As Integer = 48
        Private mHeaderText As String = ""
        Private mDrawHeader As Boolean = True
        Private mDrawFooter As Boolean = True
        Private mDrawVerticalSplitLine As Boolean = False
        Private mIcon As Icon
        Private mTopBodyColor As Color
        Private mBottomBodyColor As Color
        Private mHeaderColor As Color
        Private mHeaderTextColor As Color
        Private mHeaderFont As Font
        Private mFooterColor As Color

        Private mUserListMargin As Integer = 30
        Private mUserListPadding As Integer = 10

        Private mLastUserBottom As Integer = 0
#End Region

#Region " Windows Form Designer generated code "

        Public Sub New()
            MyBase.New()

            'This call is required by the Windows Form Designer.
            InitializeComponent()

            'Add any initialization after the InitializeComponent() call
            SetStyle(ControlStyles.ResizeRedraw, True)
            SetStyle(ControlStyles.AllPaintingInWmPaint, True)
            SetStyle(ControlStyles.UserPaint, True)
            SetStyle(ControlStyles.DoubleBuffer, True)
            SetStyle(ControlStyles.SupportsTransparentBackColor, True)
            SetStyle(ControlStyles.ContainerControl, True)

            Me.DockPadding.Bottom = mFooterHeight
            Me.DockPadding.Top = mHeaderHeight
            Me.HeaderColor = Color.FromArgb(0, 51, 153)
            Me.FooterColor = Color.FromArgb(0, 51, 153)
            Me.TopBodyColor = Color.FromArgb(85, 130, 210)
            Me.BottomBodyColor = Color.FromArgb(90, 126, 220)
            Me.HeaderTextColor = Color.FromArgb(214, 223, 245)
            Me.HeaderTextFont = New Font("Franklin Gothic Medium", 14, FontStyle.Bold)
            MyBase.BackColor = Color.Transparent
        End Sub

        'Form overrides dispose to clean up the component list.
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
            If disposing Then
                If Not (components Is Nothing) Then
                    components.Dispose()
                End If
            End If
            MyBase.Dispose(disposing)
        End Sub

        'Required by the Windows Form Designer
        Private components As System.ComponentModel.IContainer

        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        Friend WithEvents UserList As UserListPanel
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            Me.UserList = New Phoenix.Forms.Login.XPLoginScreen.UserListPanel
            Me.SuspendLayout()
            '
            'UserList
            '
            Me.UserList.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
                        Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
            Me.UserList.AutoScroll = True
            Me.UserList.BackColor = System.Drawing.Color.Transparent
            Me.UserList.CausesValidation = False
            Me.UserList.Location = New System.Drawing.Point(549, 16)
            Me.UserList.Name = "UserList"
            Me.UserList.Size = New System.Drawing.Size(296, 568)
            Me.UserList.TabIndex = 0
            '
            'XPLoginScreen
            '
            Me.Controls.Add(Me.UserList)
            Me.Name = "XPLoginScreen"
            Me.Size = New System.Drawing.Size(869, 635)
            Me.ResumeLayout(False)

        End Sub

#End Region

#Region " Event Handlers "
        Private Sub Form_Layout(ByVal sender As Object, ByVal e As LayoutEventArgs) Handles MyBase.Layout
            SuspendLayout()

            Dim DesireHeight As Integer
            If UserList.Controls.Count <> 0 Then
                DesireHeight = UserList.Controls.Count * (UserList.Controls(0).Height + mUserListPadding) - mUserListPadding
            Else
                DesireHeight = 0
            End If

            Dim MaxHeight As Integer = Me.Height - 2 * mUserListMargin - HeaderHeight - FooterHeight
            Dim FinalHeight As Integer = IIf(DesireHeight > MaxHeight, MaxHeight, DesireHeight)

            UserList.Left = Me.Width / 2 + mUserListMargin
            UserList.Top = (Height - FinalHeight) / 2
            UserList.Height = FinalHeight
 
            ResumeLayout()
        End Sub


#End Region

#Region " Methods "
        Public Sub AddLogin(ByVal Name As String)
            AddLogin(Name, String.Empty, False, Nothing)
        End Sub

        Public Sub AddLogin(ByVal Name As String, ByVal Description As String)
            AddLogin(Name, Description, False, Nothing)
        End Sub

        Public Function AddLogin(ByVal Name As String, ByVal Description As String, ByVal HasPwd As Boolean, ByVal Tag As Object) As XPLoginEntry
            Dim box As XPLoginEntry = New XPLoginEntry
            Dim offset As Integer = 0

            If UserList.Controls.Count <> 0 Then
                Dim last As Control = UserList.Controls(UserList.Controls.Count - 1)
                offset = last.Top + last.Height + mUserListPadding
            End If

            box.UserName = Name
            box.HelpString = Description
            box.HasPassword = HasPwd
            box.Tag = Tag


            box.Left = mUserListPadding - UserList.AutoScrollPosition.X
            box.Top = offset
            AddHandler box.Login, AddressOf LoginBox_Login
            AddHandler box.EnterPassword, AddressOf LoginBox_EnterPassword
            UserList.Controls.Add(box)

            Return box
        End Function

        Private Sub LoginBox_EnterPassword(ByVal sender As Object, ByVal e As EventArgs)
            Dim box As XPLoginEntry = CType(sender, XPLoginEntry)
            Login(box, box.txtPwd.Text)
        End Sub

        Private Sub LoginBox_Login(ByVal sender As Object, ByVal e As LoginEventArgs)
            Login(sender, e.Password)
        End Sub

        Private Sub Login(ByVal box As XPLoginEntry, ByVal pwd As String)
            If Not TryLogin(box.Tag, pwd) Then
                box.txtPwd.Text = ""
            End If
        End Sub

        Protected Overridable Function TryLogin(ByVal UserTag As Object, ByVal Password As String)
            Return True
        End Function

#End Region


#Region " Public Properties "

        ''' <summary>
        ''' </summary>
        ''' <value></value>
        ''' <remarks>
        ''' </remarks>
        <Description("Top color"), Category("Appearance")> _
        Public Property TopBodyColor() As Color
            Get
                Return mTopBodyColor
            End Get
            Set(ByVal Value As Color)
                mTopBodyColor = Value
            End Set
        End Property

        ''' <summary>
        ''' </summary>
        ''' <value></value>
        ''' <remarks>
        ''' </remarks>
        <Description("Header color"), Category("Appearance")> _
        Public Property HeaderColor() As Color
            Get
                Return mHeaderColor
            End Get
            Set(ByVal Value As Color)
                mHeaderColor = Value
            End Set
        End Property

        ''' <summary>
        ''' </summary>
        ''' <value></value>
        ''' <remarks>
        ''' </remarks>
        <Description("Footer color"), Category("Appearance")> _
        Public Property FooterColor() As Color
            Get
                Return mFooterColor
            End Get
            Set(ByVal Value As Color)
                mFooterColor = Value
            End Set
        End Property

        ''' <summary>
        ''' </summary>
        ''' <value></value>
        ''' <remarks>
        ''' </remarks>
        <Description("Header font"), Category("Appearance")> _
        Public Property HeaderTextFont() As Font
            Get
                Return mHeaderFont
            End Get
            Set(ByVal Value As Font)
                mHeaderFont = Value
            End Set
        End Property

        ''' <summary>
        ''' </summary>
        ''' <value></value>
        ''' <remarks>
        ''' </remarks>
        <Description("Header text color"), Category("Appearance")> _
        Public Property HeaderTextColor() As Color
            Get
                Return mHeaderTextColor
            End Get
            Set(ByVal Value As Color)
                mHeaderTextColor = Value
            End Set
        End Property

        ''' <summary>
        ''' </summary>
        ''' <value></value>
        ''' <remarks>
        ''' </remarks>
        <Description("Bottom color"), Category("Appearance")> _
        Public Property BottomBodyColor() As Color
            Get
                Return mBottomBodyColor
            End Get
            Set(ByVal Value As Color)
                mBottomBodyColor = Value
            End Set
        End Property

        ''' <summary>
        ''' Caption text
        ''' </summary>
        ''' <value>String</value>
        ''' <remarks>
        ''' This string will be displayed as caption text in the header area. 
        ''' </remarks>
        ''' -----------------------------------------------------------------------------
        <Description("Caption text."), DefaultValue(""), Category("Appearance"), Localizable(True)> _
        Public Property HeaderText() As String
            Get
                Return mHeaderText
            End Get
            Set(ByVal value As String)
                mHeaderText = value
                Invalidate()
            End Set
        End Property

        ''' <summary>
        ''' Icon to be displayed in the left top corner
        ''' </summary>
        ''' <value>Icon</value>
        ''' <remarks>
        ''' When setting this property a 32x32 pixel icon is displayed in the left top corner of the control
        ''' </remarks>
        <Description("Icon to be displayed in the left top corner"), Category("Appearance"), DefaultValue(GetType(Icon), "")> _
        Public Property Icon() As Icon
            Get
                Return mIcon
            End Get

            Set(ByVal value As Icon)
                mIcon = value
                Invalidate()
            End Set
        End Property

        ''' <summary>
        ''' Height of the Standard header
        ''' </summary>
        ''' <value>Integer</value>
        ''' <remarks>
        ''' by changing the value you can resize the header portion of the control
        ''' </remarks>
        <Description("Height of the Standard header"), Category("Appearance"), DefaultValue(48)> _
        Public Property HeaderHeight() As Integer
            Get
                Return mHeaderHeight
            End Get
            Set(ByVal value As Integer)
                mHeaderHeight = value
                Me.DockPadding.Top = value
                Invalidate()
            End Set
        End Property

        ''' <summary>
        ''' Height of the Standard footer
        ''' </summary>
        ''' <value>Integer</value>
        ''' <remarks>
        ''' by changing the value you can resize the footer portion of the control
        ''' </remarks>
        <Description("Height of the Standard footer"), Category("Appearance"), DefaultValue(48)> _
        Public Property FooterHeight() As Integer
            Get
                Return mFooterHeight
            End Get
            Set(ByVal value As Integer)
                mFooterHeight = value
                Me.DockPadding.Bottom = value
                Invalidate()
            End Set
        End Property

        ''' <summary>
        ''' Draw a vertical split line in the middle of the control
        ''' </summary>
        ''' <value>Boolean</value>
        ''' <remarks>
        ''' when set to true a thin vertical gradient line is drawn in the center of the 
        ''' body area
        ''' </remarks>
        <Description("Draw a vertical split line in the middle of the control"), Category("Appearance"), DefaultValue(False)> _
        Public Property DrawVerticalSplitLine() As Boolean
            Get
                Return mDrawVerticalSplitLine
            End Get

            Set(ByVal value As Boolean)
                mDrawVerticalSplitLine = value
                Invalidate()
            End Set
        End Property

        ''' <summary>
        ''' returns the usable region as RectangleF
        ''' </summary>
        ''' <value>Rectangle</value>
        ''' <remarks>
        ''' used for the designer. internal only
        ''' </remarks>
        <Description("returns the usable region as RectangleF"), Browsable(False)> _
        Friend ReadOnly Property WorkspaceRect() As Rectangle
            Get
                Return New Rectangle(0, mHeaderHeight + 1, Me.Width - 1, Me.Height - CInt(IIf(mDrawHeader, mHeaderHeight, 0)) - CInt(IIf(mDrawFooter, mFooterHeight, 0)) - 2)
            End Get
        End Property

#End Region

#Region " Private Properties"
        ''' <summary>
        ''' </summary>
        ''' <value></value>
        ''' <remarks>
        ''' </remarks>
        Private Property DrawHeader() As Boolean
            Get
                Return mDrawHeader
            End Get

            Set(ByVal value As Boolean)
                mDrawHeader = value
                Invalidate()
            End Set
        End Property



        ''' <summary>
        ''' </summary>
        ''' <value></value>
        ''' <remarks>
        ''' </remarks>
        Private Property DrawFooter() As Boolean
            Get
                Return mDrawFooter
            End Get

            Set(ByVal value As Boolean)
                mDrawFooter = value
                Invalidate()
            End Set
        End Property

#End Region

#Region " Custom Painting "
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            e.Graphics.SmoothingMode = SmoothingMode.HighQuality

            Dim rectHeader As New RectangleF(0, 0, Me.Width, HeaderHeight)
            Dim rectFooter As New RectangleF(0, Me.Height - FooterHeight, Me.Width, FooterHeight)
            Dim rectText As RectangleF
            Dim rectBody As New RectangleF(0, HeaderHeight, Me.Width, Me.Height - CInt(IIf(mDrawHeader, HeaderHeight, 0)) - CInt(IIf(mDrawFooter, FooterHeight, 0)))
            Dim brushBody As New LinearGradientBrush(rectBody, TopBodyColor, BottomBodyColor, LinearGradientMode.ForwardDiagonal)

            Dim stringFmt As New StringFormat
            stringFmt.Alignment = StringAlignment.Near
            stringFmt.LineAlignment = StringAlignment.Center
            stringFmt.Trimming = StringTrimming.EllipsisCharacter

            e.Graphics.FillRectangle(brushBody, rectBody)

            If mDrawHeader Then
                e.Graphics.FillRectangle(New SolidBrush(HeaderColor), rectHeader)

                e.Graphics.FillRectangle( _
                    New LinearGradientBrush( _
                        New RectangleF(0, HeaderHeight, CInt(1 + Me.Width / 2), 2), _
                        HeaderColor, _
                        ControlPaint.Light(HeaderColor), LinearGradientMode.Horizontal), _
                    New RectangleF(0, HeaderHeight, CInt(1 + Me.Width / 2), 2))

                e.Graphics.FillRectangle( _
                    New LinearGradientBrush( _
                        New RectangleF(CInt(Me.Width / 2), HeaderHeight, CInt(Me.Width / 2), 2), _
                        ControlPaint.Light(HeaderColor), _
                        HeaderColor, LinearGradientMode.Horizontal), _
                    New RectangleF(CInt(Me.Width / 2), HeaderHeight, CInt(Me.Width / 2), 2))


                If Not mIcon Is Nothing Then
                    e.Graphics.DrawIcon(New Icon(mIcon, 48, 48), New Rectangle(10, 10, 48, 48))
                    rectText = New RectangleF(68, 0, Me.Width - 78, HeaderHeight)
                Else
                    rectText = New RectangleF(10, 0, Me.Width - 20, HeaderHeight)
                End If

                e.Graphics.DrawString(HeaderText, HeaderTextFont, _
                    New SolidBrush(HeaderTextColor), rectText, stringFmt)
            End If

            If DrawFooter Then
                e.Graphics.FillRectangle(New SolidBrush(FooterColor), rectFooter)

                e.Graphics.FillRectangle( _
                    New LinearGradientBrush( _
                        New RectangleF(0, Me.Height - FooterHeight, CInt(1 + Me.Width / 2), 2), _
                        FooterColor, _
                        Color.FromArgb(253, 157, 53), LinearGradientMode.Horizontal), _
                    New RectangleF(0, Me.Height - FooterHeight, CInt(1 + Me.Width / 2), 2))

                e.Graphics.FillRectangle( _
                    New LinearGradientBrush( _
                        New RectangleF(CInt(Me.Width / 2), Me.Height - FooterHeight, CInt(Me.Width / 2), 2), _
                        Color.FromArgb(253, 157, 53), _
                        FooterColor, LinearGradientMode.Horizontal), _
                    New RectangleF(CInt(Me.Width / 2), Me.Height - FooterHeight, CInt(Me.Width / 2), 2))


                If Not Icon Is Nothing Then
                    e.Graphics.DrawIcon(New Icon(Icon, 48, 48), New Rectangle(10, 10, 48, 48))
                    rectText = New RectangleF(68, 0, Me.Width - 78, HeaderHeight)
                Else
                    rectText = New RectangleF(10, 0, Me.Width - 20, HeaderHeight)
                End If

                e.Graphics.DrawString(HeaderText, HeaderTextFont, _
                    New SolidBrush(HeaderTextColor), rectText, stringFmt)
            End If

            If DrawVerticalSplitLine Then
                Dim rectsplit As New RectangleF(rectBody.Left + rectBody.Width / 2, rectBody.Top, 0.5, rectBody.Height)
                Dim brushsplit As New LinearGradientBrush(rectsplit, TopBodyColor, BottomBodyColor, LinearGradientMode.Vertical)
                Dim blendsplit As New ColorBlend
                Dim cols As Color() = {TopBodyColor, Color.WhiteSmoke, BottomBodyColor}
                Dim pts As Single() = {0, 0.5, 1}

                blendsplit.Colors = cols
                blendsplit.Positions = pts
                brushsplit.InterpolationColors = blendsplit
                e.Graphics.FillRectangle(brushsplit, rectsplit)

                brushsplit.Dispose()
            End If


        End Sub

#End Region

    End Class
End Namespace
